"""每日学习服务"""
from typing import Dict, Any, List, Optional
from datetime import datetime, timedelta
from app.ai.question_generator import question_generator
from app.db.question_bank import get_question_by_id
from app.core.database import RedisClient


class DailyLearningService:
    """每日学习服务"""
    
    def __init__(self):
        # 无论Redis是否可用，都初始化内存存储（作为备份）
        self._memory_storage = {}
        self._daily_records = {}
        self._daily_completed = {}
        self._daily_questions_cache = {}  # 每日题目列表缓存
        
        try:
            self.redis = RedisClient.get_client()
            # 测试连接
            self.redis.ping()
        except Exception as e:
            print(f"警告: Redis连接失败，将使用内存存储: {e}")
            self.redis = None
    
    async def get_daily_questions(
        self,
        user_id: str,
        plan_id: str,
        date: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        获取每日学习题目
        
        Args:
            user_id: 用户ID
            plan_id: 计划ID
            date: 日期（YYYY-MM-DD），默认今天
            
        Returns:
            每日学习任务
        """
        if not date:
            date = datetime.now().strftime("%Y-%m-%d")
        
        # 从计划中获取每日目标
        daily_questions = 30  # 默认值
        if self.redis:
            try:
                plan_key = f"plan:{plan_id}"
                if self.redis.exists(plan_key):
                    plan_data = self.redis.hgetall(plan_key)
                    if plan_data:
                        # 处理 bytes 类型
                        if isinstance(plan_data, dict):
                            daily_questions = int(plan_data.get("daily_target_questions", 30))
            except Exception as e:
                print(f"⚠️ Redis操作失败: {e}")
        
        # 如果Redis没有，尝试从文件存储获取
        if daily_questions == 30:
            try:
                from app.services.file_storage_service import file_storage_service
                plan_key = f"plan:{plan_id}"
                if file_storage_service.exists(plan_key):
                    plan_data = file_storage_service.hgetall(plan_key)
                    if plan_data:
                        daily_questions = int(plan_data.get("daily_target_questions", 30))
            except Exception as e:
                print(f"⚠️ 文件存储读取计划失败: {e}")
        
        # 检查是否已经为今天生成过题目列表（每天生成一次固定列表）
        daily_questions_key = f"daily_questions:{user_id}:{date}"
        question_ids = []
        completed_questions = []  # 初始化变量，确保总是有定义
        
        # 尝试从缓存获取今天已生成的题目列表
        if self.redis:
            try:
                cached_questions = self.redis.get(daily_questions_key)
                if cached_questions:
                    import json
                    if isinstance(cached_questions, bytes):
                        cached_questions = cached_questions.decode('utf-8')
                    question_ids = json.loads(cached_questions)
                    print(f"✅ [每日学习] 从Redis缓存获取今日题目列表，共 {len(question_ids)} 道题")
            except Exception as e:
                print(f"⚠️ Redis操作失败: {e}")
        
        # 如果Redis没有，尝试从文件存储获取
        if not question_ids:
            try:
                from app.services.file_storage_service import file_storage_service
                cached_questions = file_storage_service.get(daily_questions_key)
                if cached_questions:
                    import json
                    if isinstance(cached_questions, str):
                        question_ids = json.loads(cached_questions)
                    else:
                        question_ids = cached_questions
                    print(f"✅ [每日学习] 从文件存储获取今日题目列表，共 {len(question_ids)} 道题")
            except Exception as e:
                print(f"⚠️ 文件存储读取失败: {e}")
        
        # 如果Redis和文件存储都没有，尝试从内存缓存获取
        if not question_ids:
            if hasattr(self, '_daily_questions_cache') and daily_questions_key in self._daily_questions_cache:
                question_ids = self._daily_questions_cache[daily_questions_key]
                print(f"✅ [每日学习] 从内存缓存获取今日题目列表，共 {len(question_ids)} 道题")
        
        # 如果没有缓存，生成新的题目列表
        if not question_ids:
            # 获取已完成的题目（避免重复）
            completed_questions = []
            if self.redis:
                try:
                    completed_key = f"daily_completed:{user_id}:{date}"
                    completed_set = self.redis.smembers(completed_key) or set()
                    completed_questions = [q.decode('utf-8') if isinstance(q, bytes) else q for q in completed_set]
                except Exception as e:
                    print(f"⚠️ Redis操作失败: {e}")
            
            # 如果Redis没有，尝试从文件存储获取
            if not completed_questions:
                try:
                    from app.services.file_storage_service import file_storage_service
                    completed_key = f"daily_completed:{user_id}:{date}"
                    completed_set = file_storage_service.smembers(completed_key)
                    completed_questions = list(completed_set) if completed_set else []
                except Exception as e:
                    print(f"⚠️ 文件存储读取失败: {e}")
            
            # 如果Redis和文件存储都没有，使用内存存储
            if not completed_questions:
                memory_key = f"{user_id}:{date}"
                if memory_key in self._daily_completed:
                    completed_questions = list(self._daily_completed[memory_key])
                elif memory_key in self._memory_storage:
                    completed_questions = list(self._memory_storage[memory_key])
            
            # 获取用户历史学习记录（排除所有已做过的题目，不仅仅是今天的）
            historical_completed = []
            if self.redis:
                try:
                    # 获取最近30天的完成记录
                    for i in range(30):
                        check_date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d")
                        check_key = f"daily_completed:{user_id}:{check_date}"
                        check_set = self.redis.smembers(check_key) or set()
                        historical_completed.extend([q.decode('utf-8') if isinstance(q, bytes) else q for q in check_set])
                except Exception as e:
                    print(f"⚠️ Redis获取历史记录失败: {e}")
            
            # 如果Redis没有，尝试从文件存储获取
            if not historical_completed:
                try:
                    from app.services.file_storage_service import file_storage_service
                    for i in range(30):
                        check_date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d")
                        check_key = f"daily_completed:{user_id}:{check_date}"
                        check_set = file_storage_service.smembers(check_key)
                        if check_set:
                            historical_completed.extend(list(check_set))
                except Exception as e:
                    print(f"⚠️ 文件存储获取历史记录失败: {e}")
            
            # 如果Redis和文件存储都没有，从内存存储获取历史记录
            if not historical_completed:
                for i in range(30):
                    check_date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d")
                    check_key = f"{user_id}:{check_date}"
                    if check_key in self._daily_completed:
                        historical_completed.extend(list(self._daily_completed[check_key]))
            
            # 合并所有需要排除的题目
            all_excluded = list(set(completed_questions + historical_completed))
            print(f"🔍 [每日学习] 排除已完成的题目: {len(all_excluded)} 道")
            
            # 优先使用LLM动态生成题目
            question_ids = []
            generated_questions = []
            
            try:
                # 获取用户薄弱环节分析
                from app.services.progress_service import progress_service
                weakness_analysis = await progress_service.get_weakness_analysis(user_id)
                
                print(f"🤖 [每日学习] 使用LLM动态生成题目（按法考科目权重，渐进式训练：简单->中等->困难）...")
                generated_questions = await question_generator.generate_questions_with_llm(
                    user_id=user_id,
                    count=daily_questions,
                    weakness_analysis=weakness_analysis,
                    progressive_training=True  # 启用渐进式训练
                )
                
                if generated_questions and len(generated_questions) > 0:
                    # 保存生成的题目到临时存储
                    from app.services.question_storage_service import question_storage_service
                    storage_result = question_storage_service.add_temporary_questions(
                        generated_questions,
                        expire_days=7
                    )
                    print(f"✅ [每日学习] 已保存 {storage_result['added']} 道LLM生成的题目到临时存储")
                    
                    # 提取题目ID
                    question_ids = [q.get("question_id") for q in generated_questions if q.get("question_id")]
                    print(f"✅ [每日学习] LLM成功生成 {len(question_ids)} 道题目")
                else:
                    print(f"⚠️ [每日学习] LLM生成失败，未生成有效题目")
                    
            except Exception as e:
                print(f"⚠️ [每日学习] LLM生成题目失败: {e}，将使用题库推荐")
                import traceback
                traceback.print_exc()
            
            # 如果LLM生成失败或数量不足，使用题库推荐补充
            if not question_ids or len(question_ids) < daily_questions * 0.5:
                remaining_count = daily_questions - len(question_ids)
                print(f"📚 [每日学习] 使用题库推荐补充 {remaining_count} 道题目...")
                
                try:
                    # 从题库推荐（排除已生成的题目）
                    recommended_ids = await question_generator.recommend_questions_with_llm(
                        user_id,
                        count=remaining_count,
                        exclude_question_ids=all_excluded + question_ids
                    )
                    
                    if not recommended_ids or len(recommended_ids) < remaining_count * 0.5:
                        # 如果推荐数量不足，使用基础推荐
                        base_recommended = await question_generator.recommend_questions(
                            user_id,
                            count=remaining_count,
                            exclude_question_ids=all_excluded + question_ids,
                            include_review_questions=True,
                            review_ratio=0.2
                        )
                        question_ids.extend(base_recommended)
                    else:
                        question_ids.extend(recommended_ids)
                        
                except Exception as e:
                    print(f"⚠️ [每日学习] 题库推荐失败: {e}，使用基础推荐")
                    base_recommended = await question_generator.recommend_questions(
                        user_id,
                        count=remaining_count,
                        exclude_question_ids=all_excluded + question_ids,
                        include_review_questions=True,
                        review_ratio=0.2
                    )
                    question_ids.extend(base_recommended)
            
            # 确保题目数量不超过目标
            question_ids = question_ids[:daily_questions]
            print(f"✅ [每日学习] 最终题目列表：{len(question_ids)} 道（LLM生成: {len(generated_questions)} 道，题库推荐: {len(question_ids) - len(generated_questions)} 道）")
            
            # 保存今天生成的题目列表（缓存到当天结束）
            if question_ids:
                saved_to_redis = False
                if self.redis:
                    try:
                        import json
                        import time
                        # 计算到当天结束的秒数
                        now = datetime.now()
                        end_of_day = datetime(now.year, now.month, now.day, 23, 59, 59)
                        seconds_until_midnight = int((end_of_day - now).total_seconds()) + 1
                        self.redis.setex(
                            daily_questions_key,
                            seconds_until_midnight,
                            json.dumps(question_ids, ensure_ascii=False)
                        )
                        saved_to_redis = True
                        print(f"✅ [每日学习] 已保存今日题目列表到Redis，共 {len(question_ids)} 道题，有效期至当天结束")
                    except Exception as e:
                        print(f"⚠️ Redis保存题目列表失败: {e}，将使用文件存储")
                
                # 如果Redis不可用，使用文件存储
                if not saved_to_redis:
                    try:
                        from app.services.file_storage_service import file_storage_service
                        import json
                        import time
                        now = datetime.now()
                        end_of_day = datetime(now.year, now.month, now.day, 23, 59, 59)
                        seconds_until_midnight = int((end_of_day - now).total_seconds()) + 1
                        file_storage_service.setex(
                            daily_questions_key,
                            seconds_until_midnight,
                            json.dumps(question_ids, ensure_ascii=False)
                        )
                        print(f"✅ [文件存储] 已保存今日题目列表到文件，共 {len(question_ids)} 道题")
                    except Exception as e:
                        print(f"⚠️ 文件存储保存失败: {e}")
                
                # 无论是否保存成功，都保存到内存缓存（作为最后的备份）
                if not hasattr(self, '_daily_questions_cache'):
                    self._daily_questions_cache = {}
                self._daily_questions_cache[daily_questions_key] = question_ids
        
        # 获取题目详情（优先从临时存储获取LLM生成的题目）
        questions = []
        from app.services.question_storage_service import question_storage_service
        
        for qid in question_ids:
            # 先尝试从临时存储获取（LLM生成的题目）
            question_data = question_storage_service.get_temporary_question(qid)
            
            # 如果临时存储没有，从常规题库获取
            if not question_data:
                question_data = get_question_by_id(qid)
            
            if question_data:
                # 自动修正题目类型：如果正确答案包含多个选项，自动按多选题处理
                question_type = question_data.get("type", "single_choice")
                correct_answer = question_data.get("correct_answer", "")
                
                # 检查正确答案是否包含多个选项
                import json
                import re
                def extract_options_count(answer_text: str) -> int:
                    """从答案文本中提取选项数量"""
                    if not answer_text:
                        return 0
                    count = 0
                    # 尝试解析JSON格式
                    try:
                        if answer_text.strip().startswith('['):
                            data = json.loads(answer_text)
                            if isinstance(data, list):
                                return len(data)
                    except:
                        pass
                    # 提取"选项X"格式的所有选项
                    matches = re.findall(r'选项([A-D])', answer_text)
                    return len(set(matches))
                
                correct_options_count = extract_options_count(correct_answer)
                if correct_options_count > 1 and question_type == "single_choice":
                    # 自动修正为多选题
                    question_type = "indefinite_choice"  # 使用indefinite_choice，因为不确定是multiple_choice还是indefinite_choice
                    print(f"⚠️ 题目 {qid} 类型标记为单选，但正确答案包含 {correct_options_count} 个选项，自动修正为不定项选择题")
                
                # 不返回正确答案（答题时隐藏）
                questions.append({
                    "question_id": question_data.get("question_id"),
                    "content": question_data.get("content"),
                    "options": question_data.get("options", []),
                    "type": question_type,  # 使用修正后的类型
                    "difficulty": question_data.get("difficulty", "medium"),
                    "knowledge_points": question_data.get("knowledge_points", []),
                    "category": question_data.get("category"),
                    "subject": question_data.get("subject")
                })
        
        # 检查今日完成状态
        completed_count = len(completed_questions)
        if completed_count >= daily_questions:
            status = "completed"
        elif completed_count > 0:
            status = "in_progress"
        else:
            status = "pending"
        
        return {
            "date": date,
            "plan_id": plan_id,
            "user_id": user_id,
            "total_questions": len(questions),
            "target_questions": daily_questions,
            "completed_questions": completed_count,
            "questions": questions,
            "status": status,  # pending, in_progress, completed
            "progress": completed_count / daily_questions if daily_questions > 0 else 0
        }
    
    async def submit_daily_answer(
        self,
        user_id: str,
        plan_id: str,
        question_id: str,
        user_answer: str,
        user_notes: Optional[str] = None,
        marked_wrong: bool = False
    ) -> Dict[str, Any]:
        """
        提交每日学习答案（支持标记错误和备注）
        
        Args:
            user_id: 用户ID
            plan_id: 计划ID
            question_id: 题目ID
            user_answer: 用户答案
            user_notes: 用户备注（分析原因）
            marked_wrong: 是否标记为错误
            
        Returns:
            批改结果和错误分析
        """
        from app.services.training_service import training_service
        from app.ai.evaluation_engine import get_evaluation_engine
        
        # 获取题目数据
        question_data = get_question_by_id(question_id)
        if not question_data:
            return {"error": "题目不存在"}
        
        correct_answer = question_data.get("correct_answer", "")
        question_type = question_data.get("type", "single_choice")
        
        # 提取选项标识（支持单选和多选）
        import re
        import json
        
        def extract_options(answer_text: str) -> set:
            """从答案文本中提取所有选项标识"""
            if not answer_text:
                return set()
            
            options = set()
            
            # 尝试解析JSON格式（如：[{"id":"A","text":"..."},{"id":"C","text":"..."}]）
            try:
                if answer_text.strip().startswith('['):
                    data = json.loads(answer_text)
                    if isinstance(data, list):
                        for item in data:
                            if isinstance(item, dict):
                                option_id = item.get("id", "")
                                if option_id:
                                    options.add(f"选项{option_id}")
            except:
                pass
            
            # 提取"选项X"格式的所有选项（支持"选项A、选项C"格式）
            matches = re.findall(r'选项([A-D])', answer_text)
            for match in matches:
                options.add(f"选项{match}")
            
            return options
        
        # 判断是单选还是多选
        # 先检查正确答案格式，如果正确答案包含多个选项，自动按多选题处理
        correct_options_set = extract_options(correct_answer)
        has_multiple_correct_answers = len(correct_options_set) > 1
        
        # 如果正确答案有多个选项，但题目类型是单选，自动修正为多选题
        if has_multiple_correct_answers and question_type == "single_choice":
            print(f"⚠️ 题目 {question_id} 类型标记为单选，但正确答案包含多个选项，自动按多选题处理")
            is_multiple_choice = True
        else:
            is_multiple_choice = question_type in ["multiple_choice", "indefinite_choice"]
        
        # 答案判断结果
        is_correct = False
        is_partially_correct = False
        missing_options = []  # 缺少的选项
        extra_options = []  # 多余的选项
        
        if is_multiple_choice:
            # 多选题：比较选项集合
            user_options = extract_options(user_answer)
            correct_options = extract_options(correct_answer)
            
            if len(user_options) == 0:
                # 未选择任何选项
                is_correct = False
                missing_options = list(correct_options)
            elif user_options == correct_options:
                # 完全正确
                is_correct = True
            elif user_options.issubset(correct_options):
                # 部分正确：用户选择的都在正确答案内，但不全
                is_partially_correct = True
                is_correct = False
                missing_options = list(correct_options - user_options)
            else:
                # 有错误选项：用户选择了不在正确答案中的选项
                is_correct = False
                missing_options = list(correct_options - user_options)
                extra_options = list(user_options - correct_options)
        else:
            # 单选题：只比较第一个选项
            # 先从正确答案中提取选项（支持JSON格式和简单格式）
            correct_options_set = extract_options(correct_answer)
            user_options_set = extract_options(user_answer)
            
            # 单选题应该只有一个正确选项
            if len(correct_options_set) == 1 and len(user_options_set) == 1:
                # 比较选项集合
                is_correct = user_options_set == correct_options_set
                if not is_correct:
                    # 提取正确选项的ID（去掉"选项"前缀）
                    correct_option_id = list(correct_options_set)[0].replace("选项", "")
                    missing_options = [correct_option_id]
            else:
                # 兼容旧逻辑：使用正则表达式提取
                user_option = re.search(r'选项([A-D])', user_answer) if user_answer else None
                correct_option = re.search(r'选项([A-D])', correct_answer) if correct_answer else None
                is_correct = (
                    user_option and correct_option and 
                    user_option.group(1) == correct_option.group(1)
                )
                if not is_correct and correct_option:
                    missing_options = [correct_option.group(1)]
        
        # 如果用户标记为错误，即使答案正确也按错误处理
        if marked_wrong:
            is_correct = False
            is_partially_correct = False
        
        # 错误分析
        error_analysis = None
        unmastered_knowledge_points = []
        thinking_analysis = None
        partial_correct_feedback = None  # 部分正确的批注
        
        # 处理部分正确的情况
        if is_partially_correct:
            # 分析缺少选项对应的知识点
            missing_knowledge_points = []
            
            # 从题目解析中提取缺少选项对应的知识点
            explanation = question_data.get("explanation", "")
            options = question_data.get("options", [])
            
            # 尝试从解析中匹配缺少的选项
            for missing_opt in missing_options:
                opt_id = missing_opt.replace("选项", "")
                # 查找该选项在选项列表中的位置
                for opt_text in options:
                    if opt_text.startswith(f"选项{opt_id}"):
                        # 可以在这里添加更复杂的知识点提取逻辑
                        # 目前使用题目的所有知识点，但标记为部分未掌握
                        break
            
            # 如果缺少选项，标记相关知识点为未掌握
            if missing_options:
                # 获取题目的所有知识点
                all_knowledge_points = question_data.get("knowledge_points", [])
                # 根据缺少的选项数量，按比例标记知识点
                if all_knowledge_points:
                    # 计算缺少的比例
                    missing_ratio = len(missing_options) / len(correct_options) if correct_options else 0
                    # 标记相应比例的知识点为未掌握
                    num_missing_kp = max(1, int(len(all_knowledge_points) * missing_ratio))
                    missing_knowledge_points = all_knowledge_points[:num_missing_kp]
                else:
                    # 如果没有知识点，根据选项生成提示
                    missing_knowledge_points = [f"选项{opt.replace('选项', '')}相关知识点" for opt in missing_options]
            
            unmastered_knowledge_points = missing_knowledge_points
            
            # 生成部分正确的批注
            missing_options_text = "、".join([opt.replace("选项", "选项") for opt in missing_options])
            partial_correct_feedback = {
                "is_partial": True,
                "message": f"您的答案部分正确，但缺少了 {missing_options_text}。",
                "missing_options": missing_options,
                "missing_knowledge_points": missing_knowledge_points,
                "feedback": f"您已掌握了部分知识点，但还需要加强对以下知识点的理解：{', '.join(missing_knowledge_points) if missing_knowledge_points else '相关知识点'}。"
            }
        
        # 详细的分析（包括做题思路、正确答案解释）
        # 答对时：分析为什么正确，巩固正确思路
        # 答错时：分析错误原因，指出问题
        detailed_analysis = None
        
        if is_correct and not marked_wrong:
            # 答对时，使用大模型分析为什么正确，巩固正确思路
            try:
                evaluation_engine = get_evaluation_engine()
                import asyncio
                detailed_analysis = await asyncio.wait_for(
                    evaluation_engine.generate_correct_answer_analysis(
                        question_content=question_data.get("content", ""),
                        question_options=question_data.get("options", []),
                        user_answer=user_answer,
                        correct_answer=correct_answer,
                        explanation=question_data.get("explanation", ""),
                        knowledge_points=question_data.get("knowledge_points", [])
                    ),
                    timeout=60.0  # 60秒超时，给大模型充足时间
                )
            except asyncio.TimeoutError:
                print("生成正确答案分析超时（60秒）")
                detailed_analysis = None
            except Exception as e:
                print(f"生成正确答案分析失败: {e}")
                detailed_analysis = None
        
        if not is_correct or marked_wrong:
            # 使用评估引擎分析错误
            try:
                evaluation_engine = get_evaluation_engine()
                error_classification = await evaluation_engine.classify_error_type(
                    question_data.get("content", ""),
                    user_answer,
                    correct_answer
                )
                
                # 生成详细的错误分析（包括做题思路、正确答案解释、错误点分析）
                # 添加超时控制，避免请求超时（增加到20秒，给大模型更多时间）
                try:
                    import asyncio
                    detailed_error_analysis = await asyncio.wait_for(
                        evaluation_engine.generate_detailed_error_analysis(
                            question_content=question_data.get("content", ""),
                            question_options=question_data.get("options", []),
                            user_answer=user_answer,
                            correct_answer=correct_answer,
                            explanation=question_data.get("explanation", ""),
                            knowledge_points=question_data.get("knowledge_points", [])
                        ),
                        timeout=60.0  # 60秒超时，给大模型充足时间
                    )
                except asyncio.TimeoutError:
                    print("生成详细错误分析超时（60秒），使用基础分析")
                    detailed_error_analysis = None
                except Exception as e:
                    print(f"生成详细错误分析失败: {e}")
                    detailed_error_analysis = None
                    
            except Exception as e:
                # 如果评估引擎失败，使用默认分析
                print(f"评估引擎错误: {e}")
                error_classification = {
                    "error_type": "knowledge",
                    "error_category": "unknown",
                    "details": {
                        "reason": "系统分析中，请参考题目解析和知识点"
                    }
                }
            
            error_analysis = {
                "error_type": error_classification.get("error_type"),
                "error_category": error_classification.get("error_category"),
                "error_details": error_classification.get("details", {}),
                "user_notes": user_notes,  # 用户自己的分析
                "system_analysis": error_classification.get("details", {}).get("reason", ""),
                "detailed_analysis": detailed_error_analysis  # 详细的错误分析
            }
            # 将错误分析赋值给detailed_analysis，统一变量名
            detailed_analysis = detailed_error_analysis
            
            # 提取未掌握的知识点（如果不是部分正确的情况）
            if not is_partially_correct:
                unmastered_knowledge_points = question_data.get("knowledge_points", [])
            
            # 如果有错误选项，也需要分析
            if extra_options:
                extra_options_text = "、".join([opt.replace("选项", "选项") for opt in extra_options])
                if error_analysis:
                    error_analysis["extra_options"] = extra_options
                    error_analysis["error_details"]["extra_options_message"] = f"您选择了错误的选项：{extra_options_text}。"
        
        # 如果用户提供了分析笔记，进行法律思维分析
        if user_notes:
            try:
                from app.services.legal_thinking_service import legal_thinking_service
                thinking_analysis = await legal_thinking_service.analyze_thinking_process(
                    user_id,
                    question_id,
                    user_answer,
                    user_notes,
                    correct_answer,
                    question_data.get("content", ""),
                    question_data.get("explanation", "")
                )
            except Exception as e:
                print(f"思维分析失败: {e}")
                thinking_analysis = None
        
        # 更新题目的做错/做对次数
        question_data["wrong_count"] = question_data.get("wrong_count", 0)
        question_data["correct_count"] = question_data.get("correct_count", 0)
        
        if not is_correct or marked_wrong:
            question_data["wrong_count"] += 1
        else:
            question_data["correct_count"] += 1
        
        # 更新难度评估
        from app.services.difficulty_service import difficulty_service
        difficulty_service.update_question_difficulty(question_id, is_correct)
        
        # 更新用户水平
        from app.services.user_level_service import user_level_service
        user_level_service.update_user_level(user_id, question_id, is_correct)
        
        # 保存学习记录
        today = datetime.now().strftime('%Y-%m-%d')
        record_data = {
            "question_id": question_id,
            "user_answer": user_answer,
            "correct_answer": correct_answer,
            "is_correct": is_correct,
            "marked_wrong": marked_wrong,
            "user_notes": user_notes or "",
            "error_analysis": str(error_analysis) if error_analysis else "",
            "timestamp": datetime.now().isoformat(),
            "wrong_count": question_data["wrong_count"],
            "correct_count": question_data["correct_count"]
        }
        
        # 保存到Redis（如果可用）
        saved_to_redis = False
        if self.redis:
            try:
                import json
                record_key = f"daily_record:{user_id}:{today}"
                self.redis.hset(record_key, question_id, json.dumps(record_data, ensure_ascii=False))
                self.redis.expire(record_key, 86400 * 365)  # 保存1年
                
                # 标记题目为已完成
                completed_key = f"daily_completed:{user_id}:{today}"
                self.redis.sadd(completed_key, question_id)
                self.redis.expire(completed_key, 86400 * 365)
                
                # 如果是错题，加入错题本
                if not is_correct or marked_wrong:
                    wrong_questions_key = f"wrong_questions:{user_id}"
                    self.redis.sadd(wrong_questions_key, question_id)
                
                saved_to_redis = True
            except Exception as e:
                print(f"⚠️ Redis操作失败: {e}，将使用文件存储")
        
        # 如果Redis不可用，使用文件存储
        if not saved_to_redis:
            try:
                from app.services.file_storage_service import file_storage_service
                import json
                
                record_key = f"daily_record:{user_id}:{today}"
                file_storage_service.hset(record_key, question_id, json.dumps(record_data, ensure_ascii=False))
                file_storage_service.expire(record_key, 86400 * 365)
                
                completed_key = f"daily_completed:{user_id}:{today}"
                file_storage_service.sadd(completed_key, question_id)
                file_storage_service.expire(completed_key, 86400 * 365)
                
                if not is_correct or marked_wrong:
                    wrong_questions_key = f"wrong_questions:{user_id}"
                    file_storage_service.sadd(wrong_questions_key, question_id)
                
                print(f"✅ [文件存储] 学习记录已保存到文件: {record_key}")
            except Exception as e:
                print(f"⚠️ 文件存储失败: {e}")
        
        # 无论Redis是否可用，都保存到内存存储（供进度服务读取）
        record_key = f"{user_id}:{today}"
        if record_key not in self._daily_records:
            self._daily_records[record_key] = {}
        self._daily_records[record_key][question_id] = record_data
        
        completed_key = f"{user_id}:{today}"
        if completed_key not in self._daily_completed:
            self._daily_completed[completed_key] = set()
        self._daily_completed[completed_key].add(question_id)
        
        # 格式化正确答案用于显示（将JSON格式转换为可读文本）
        def format_answer_for_display(answer_text: str) -> str:
            """将答案格式化为可读文本"""
            if not answer_text:
                return ""
            
            # 尝试解析JSON格式
            try:
                if answer_text.strip().startswith('['):
                    data = json.loads(answer_text)
                    if isinstance(data, list):
                        # 提取所有选项ID并排序
                        option_ids = []
                        for item in data:
                            if isinstance(item, dict):
                                option_id = item.get("id", "")
                                if option_id:
                                    option_ids.append(option_id)
                        if option_ids:
                            # 按字母顺序排序，然后用"、"连接
                            option_ids.sort()
                            return "、".join([f"选项{id}" for id in option_ids])
            except:
                pass
            
            # 如果不是JSON格式，直接返回原文本
            return answer_text
        
        formatted_correct_answer = format_answer_for_display(correct_answer)
        
        return {
            "question_id": question_id,
            "is_correct": is_correct,
            "is_partially_correct": is_partially_correct,  # 部分正确标识
            "user_answer": user_answer,
            "correct_answer": formatted_correct_answer,
            "explanation": question_data.get("explanation", ""),
            "marked_wrong": marked_wrong,
            "user_notes": user_notes,
            "error_analysis": error_analysis,
            "partial_correct_feedback": partial_correct_feedback,  # 部分正确的批注
            "unmastered_knowledge_points": unmastered_knowledge_points,
            "missing_options": missing_options,  # 缺少的选项
            "extra_options": extra_options,  # 多余的选项
            "thinking_analysis": thinking_analysis,  # 法律思维分析
            "detailed_analysis": detailed_analysis,  # 详细分析（答对时：为什么正确；答错时：错误分析）
            "recommendations": self._generate_recommendations(
                error_analysis,
                unmastered_knowledge_points,
                thinking_analysis,
                partial_correct_feedback
            )
        }
    
    def _generate_recommendations(
        self,
        error_analysis: Optional[Dict[str, Any]],
        unmastered_knowledge_points: List[str],
        thinking_analysis: Optional[Dict[str, Any]] = None,
        partial_correct_feedback: Optional[Dict[str, Any]] = None
    ) -> List[str]:
        """生成学习建议"""
        recommendations = []
        
        # 处理部分正确的情况
        if partial_correct_feedback:
            feedback_msg = partial_correct_feedback.get("feedback", "")
            if feedback_msg:
                recommendations.append(feedback_msg)
            else:
                # 如果没有自定义反馈，生成默认反馈
                missing_kp = partial_correct_feedback.get("missing_knowledge_points", [])
                if missing_kp:
                    recommendations.append(
                        f"您已掌握了部分知识点，但还需要加强对以下知识点的理解：{', '.join(missing_kp)}。"
                    )
        
        if unmastered_knowledge_points:
            recommendations.append(
                f"建议重点复习以下知识点：{', '.join(unmastered_knowledge_points)}"
            )
        
        if error_analysis:
            error_type = error_analysis.get("error_type")
            if error_type == "knowledge":
                recommendations.append("这是知识性错误，建议加强相关法律条文的学习")
            elif error_type == "thinking":
                recommendations.append("这是思维性错误，建议多进行案例分析训练")
            elif error_type == "technique":
                recommendations.append("这是技巧性错误，建议学习答题技巧和时间管理")
            elif error_type == "attention":
                recommendations.append("这是注意力错误，建议仔细审题，注意细节")
        
        # 添加法律思维训练建议
        if thinking_analysis:
            thinking_score = thinking_analysis.get("thinking_quality_score", 70)
            if thinking_score < 70:
                recommendations.append("💡 法律思维质量有待提升，建议加强思维训练")
            
            improvement_suggestions = thinking_analysis.get("improvement_suggestions", [])
            recommendations.extend(improvement_suggestions[:2])  # 最多添加2条思维建议
        
        return recommendations
    
    async def get_wrong_questions(self, user_id: str) -> List[Dict[str, Any]]:
        """获取错题本"""
        wrong_questions_key = f"wrong_questions:{user_id}"
        question_ids = []
        
        # 优先从Redis获取
        if self.redis:
            try:
                question_ids = list(self.redis.smembers(wrong_questions_key) or [])
            except Exception as e:
                print(f"⚠️ Redis获取错题本失败: {e}")
        
        # 如果Redis没有，尝试从文件存储获取
        if not question_ids:
            try:
                from app.services.file_storage_service import file_storage_service
                question_ids = list(file_storage_service.smembers(wrong_questions_key) or [])
            except Exception as e:
                print(f"⚠️ 文件存储获取错题本失败: {e}")
        
        wrong_questions = []
        for qid in question_ids:
            if isinstance(qid, bytes):
                qid = qid.decode('utf-8')
            question_data = get_question_by_id(qid)
            if question_data:
                # 简化实现：直接返回题目
                wrong_questions.append({
                    "question_id": question_data.get("question_id"),
                    "content": question_data.get("content"),
                    "options": question_data.get("options", []),
                    "correct_answer": question_data.get("correct_answer"),
                    "explanation": question_data.get("explanation"),
                    "knowledge_points": question_data.get("knowledge_points", []),
                    "category": question_data.get("category")
                })
        
        return wrong_questions
    
    async def get_today_statistics(
        self,
        user_id: str,
        plan_id: str,
        date: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        获取今日学习统计
        
        Args:
            user_id: 用户ID
            plan_id: 计划ID
            date: 日期（YYYY-MM-DD），默认今天
            
        Returns:
            今日学习统计
        """
        if not date:
            date = datetime.now().strftime("%Y-%m-%d")
        
        # 获取今日完成的题目记录
        today = date
        record_key = f"{user_id}:{today}"
        records = {}
        
        if self.redis:
            try:
                redis_record_key = f"daily_record:{user_id}:{today}"
                if self.redis.exists(redis_record_key):
                    import json
                    all_records = self.redis.hgetall(redis_record_key)
                    for q_id, record_json in all_records.items():
                        if isinstance(q_id, bytes):
                            q_id = q_id.decode('utf-8')
                        if isinstance(record_json, bytes):
                            record_json = record_json.decode('utf-8')
                        records[q_id] = json.loads(record_json)
            except Exception as e:
                print(f"⚠️ Redis操作失败: {e}")
        
        # 如果Redis没有，尝试从文件存储获取
        if not records:
            try:
                from app.services.file_storage_service import file_storage_service
                redis_record_key = f"daily_record:{user_id}:{today}"
                if file_storage_service.exists(redis_record_key):
                    import json
                    all_records = file_storage_service.hgetall(redis_record_key)
                    for q_id, record_json in all_records.items():
                        if isinstance(record_json, str):
                            records[q_id] = json.loads(record_json)
                        else:
                            records[q_id] = record_json
            except Exception as e:
                print(f"⚠️ 文件存储读取失败: {e}")
        
        # 从内存存储获取（作为最后的备份）
        if record_key in self._daily_records:
            records.update(self._daily_records[record_key])
        
        # 统计信息
        total_completed = len(records)
        correct_count = sum(1 for r in records.values() if r.get("is_correct", False))
        wrong_count = total_completed - correct_count
        accuracy = (correct_count / total_completed * 100) if total_completed > 0 else 0
        
        # 获取目标题目数
        daily_questions = 30  # 默认值
        if self.redis:
            try:
                plan_key = f"plan:{plan_id}"
                if self.redis.exists(plan_key):
                    plan_data = self.redis.hgetall(plan_key)
                    if plan_data:
                        if isinstance(plan_data, dict):
                            daily_questions = int(plan_data.get("daily_target_questions", 30))
            except Exception as e:
                print(f"⚠️ Redis操作失败: {e}")
        
        # 如果Redis没有，尝试从文件存储获取
        if daily_questions == 30:
            try:
                from app.services.file_storage_service import file_storage_service
                plan_key = f"plan:{plan_id}"
                if file_storage_service.exists(plan_key):
                    plan_data = file_storage_service.hgetall(plan_key)
                    if plan_data:
                        daily_questions = int(plan_data.get("daily_target_questions", 30))
            except Exception as e:
                print(f"⚠️ 文件存储读取计划失败: {e}")
        
        return {
            "date": date,
            "user_id": user_id,
            "plan_id": plan_id,
            "total_completed": total_completed,
            "target_questions": daily_questions,
            "correct_count": correct_count,
            "wrong_count": wrong_count,
            "accuracy": round(accuracy, 2),
            "is_completed": total_completed >= daily_questions,
            "progress": total_completed / daily_questions if daily_questions > 0 else 0
        }


daily_learning_service = DailyLearningService()

